﻿using System;
using System.ComponentModel;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Input;
using BaMusaSoft.RPS.DataModel;
using BaMusaSoft.RPS.ViewModel;
using BaMusaSoft.RPS.ViewModel.Infrastructure;
using GalaSoft.MvvmLight.Command;
using GalaSoft.MvvmLight.Messaging;

namespace BaMusaSoft.RPS.View
{
    /// <summary>
    /// Interaction logic for ScheduleView.xaml
    /// </summary>
    public partial class ScheduleView : UserControl
    {
        #region Fields

        private RelayCommand _addContractCommand;
        private AddContractViewModel _addContractViewModel;
        private RelayCommand _addDetailCommand;
        private AddScheduleDetailViewModel _addDetailViewModel;
        private RelayCommand _addSignerCommand;
        private AddSignerViewModel _addSignerViewModel;
        private object _messagesToken;

        #endregion
        
        public ScheduleView()
        {
            InitializeComponent();
            
        }

        #region Commands

        public ICommand AddContractCommand
        {
            get { return _addContractCommand ?? (_addContractCommand = new RelayCommand(AddContract)); }
        }

        public ICommand AddSignerCommand
        {
            get { return _addSignerCommand ?? (_addSignerCommand = new RelayCommand(AddSigner)); }
        }

        public ICommand AddDetailCommand
        {
            get { return _addDetailCommand ?? (_addDetailCommand = new RelayCommand(AddDetail)); }
        }

        private void AddContract()
        {
            IUnitOfWork unitOfWork = ((ScheduleViewModel) DataContext).UnitOfWork;
            if (_addContractViewModel == null) _addContractViewModel = new AddContractViewModel(unitOfWork);
            var addContractWindow = new AddContractWindow(_addContractViewModel);
            if (addContractWindow.ShowDialog() == true)
            {
                if (_addContractViewModel.SelectedContract != null)
                {
                    ((ScheduleViewModel) DataContext).SetContract(_addContractViewModel.SelectedContract);
                }
            }
        }

        private void AddSigner()
        {
            IUnitOfWork unitOfWork = ((ScheduleViewModel) DataContext).UnitOfWork;
            if (_addSignerViewModel == null) _addSignerViewModel = new AddSignerViewModel(unitOfWork);
            var addSignerWindow = new AddSignerWindow(_addSignerViewModel);
            if (addSignerWindow.ShowDialog() == true)
            {
                if (_addSignerViewModel.SelectedSigner != null)
                {
                    ((ScheduleViewModel) DataContext).SetSigner(_addSignerViewModel.SelectedSigner);
                }
            }
        }

        private void AddDetail()
        {
            IUnitOfWork unitOfWork = ((ScheduleViewModel) DataContext).UnitOfWork;
            if (_addDetailViewModel == null)
            {
                _addDetailViewModel = new AddScheduleDetailViewModel(unitOfWork);
                _addDetailViewModel.DetailAdded += OnDetailAdded;
            }

            var addDetailWindow = new AddScheduleDetailWindow(_addDetailViewModel);
            addDetailWindow.ShowDialog();
        }

        private void OnDetailAdded(object sender, EntityAddedEventArgs<ScheduleDetail> e)
        {
            if (e.Entity != null)
            {
                ((ScheduleViewModel) DataContext).SetDetail(e.Entity);
            }
        }

        #endregion

        private void ViewLoaded(object sender, RoutedEventArgs e)
        {
            _messagesToken = ((ScheduleViewModel)DataContext).MessageToken;
            Messenger.Default.Register<string>(this, _messagesToken, OnViewModelMessages);
            Messenger.Default.Register<ViewModelState>(this, _messagesToken, OnViewModelStateChanged);
            Messenger.Default.Register<DialogMessage>(this, _messagesToken, OnViewModelRequestConfirmation);
            txtRegDate.Focus();
        }
        


        private void ViewUnloaded(object sender, RoutedEventArgs e)
        {
            if(_addDetailViewModel != null) _addDetailViewModel.DetailAdded -= OnDetailAdded;
            Messenger.Default.Unregister<string>(this, OnViewModelMessages);
            Messenger.Default.Unregister<ViewModelState>(this, OnViewModelStateChanged);
            Messenger.Default.Unregister<DialogMessage>(this, OnViewModelRequestConfirmation);

        }

        #region "ViewModel's Messages Methods"

        private void OnViewModelMessages(string msg)
        {
            MessageBox.Show(msg);
        }

        private void OnViewModelStateChanged(ViewModelState state)
        {
            switch (state)
            {
                case ViewModelState.New:
                    txtRegDate.Focus();
                    break;
                case ViewModelState.Saved:
                    break;
                case ViewModelState.Loaded:
                    break;
                case ViewModelState.Deleted:
                    txtRegDate.Focus();
                    break;
                default:
                    throw new ArgumentOutOfRangeException("state");
            }
        }

        private void OnViewModelRequestConfirmation(DialogMessage dialog)
        {
            var result = MessageBox.Show(dialog.Content,
                                         dialog.Caption,
                                         dialog.Button,
                                         dialog.Icon,
                                         dialog.DefaultResult,
                                         dialog.Options);
            dialog.Callback(result);
        }

        #endregion

        private void OnSearchBoxSelectionChanged(object sender, SelectionChangedEventArgs e)
        {
            var selected = cmbSearch.SelectedItem as Schedule;
            if (selected != null)
            {
                ((ScheduleViewModel) DataContext).ScheduleToOpen = selected;
            }
            
        }

        private void OnDetailsGridSelectionChanged(object sender, SelectionChangedEventArgs e)
        {
            ScheduleDetail detail = dgDetails.SelectedItem as ScheduleDetail;
            if (detail != null) ((ScheduleViewModel)DataContext).SelectedDetail = detail;

        }

        private void OnContentGridKeyDown(object sender, KeyEventArgs e)
        {
            if (e.Key != Key.Enter) return;
       
            var uie = e.OriginalSource as UIElement;
            var textbox = uie as TextBox;
            if (textbox != null )
            {
                uie.MoveFocus(new TraversalRequest(FocusNavigationDirection.Next));
                e.Handled = true;
            }
        }



        

    

    }
}